package com.flyduck.modules.system.service.impl;

import com.flyduck.modules.system.domain.SysDept;
import com.flyduck.modules.system.mapper.SysDeptMapper;
import com.flyduck.modules.system.service.SysDeptService;
import com.flyduck.common.vo.QueryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: flyduck-admin
 * @description:
 * @author: flyduck
 * @create: 2020-05-06 15:16
 **/
@Service
@Transactional
public class SysDeptServiceImpl extends BaseServiceImpl implements SysDeptService {

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Override
    public Set<SysDept> findTree(QueryVo queryVo) {
        //查询所有的部门
        List<SysDept> sysDeptList = sysDeptMapper.findList(queryVo.getKeyword());
        //构造部门树结构
        return buildTree(sysDeptList);
    }

    /**
     * 根据id查询部门
     * @param id
     * @return
     */
    @Override
    public SysDept getDeptById(Long id) {
        return sysDeptMapper.selectByPrimaryKey(id);
    }

    /**
     * 保存部门
     * @param sysDept
     */
    @Override
    public void save(SysDept sysDept) {
        //新增部门初始化参数
        sysDept.setCreateName(getUser().getUsername());
        sysDept.setCreateTime(new Date());
        sysDeptMapper.insertSelective(sysDept);
    }

    /**
     * 更新部门
     * @param sysDept
     */
    @Override
    public void update(SysDept sysDept) {
        sysDept.setUpdateName(getUser().getUsername());
        sysDept.setUpdateTime(new Date());
        sysDeptMapper.updateByPrimaryKeySelective(sysDept);
    }

    /**
     * 根据部门id删除当前及以下的所有部门
     * @param id
     */
    @Override
    public void deleteById(Long id) {
        //根据id获取所有子节点的id
        Set<Long> childNodeIds = findNextNodeIds(id);
        childNodeIds.add(id);
        //遍历删除
        for (Long childNodeId : childNodeIds) {
            sysDeptMapper.deleteByPrimaryKey(childNodeId);
        }
    }

    /**
     * 根据id获取所有子节点
     * @param pid
     * @return
     */
    private Set<Long> findNextNodeIds(Long pid){
        Set<Long> childNodeIds = new HashSet<>();
        //查询子节点
        List<SysDept> childNodes = sysDeptMapper.findAllByPid(pid);
        for (SysDept sysDept : childNodes) {
            //下一级
            childNodeIds.add(sysDept.getId());
            //下一级的下一级
            Set<Long> childNodeIds1 = findNextNodeIds(sysDept.getId());
            childNodeIds.addAll(childNodeIds1);
        }
        return childNodeIds;
    }

    //构造树
    private Set<SysDept> buildTree(List<SysDept> sysDeptList){
        Set<SysDept> trees = new LinkedHashSet<>();
        //tree为空的情况
        Set<SysDept> depts = new LinkedHashSet<>();
        List<Long> deptIds = sysDeptList.stream().map(SysDept::getId).collect(Collectors.toList());
        boolean isChild;
        for (SysDept sysDept : sysDeptList) {
            isChild = false;
            //最高层级
            if(sysDept.getPid() == 0){
                trees.add(sysDept);
            }
            //把子层级加到上一层级下面
            for (SysDept dept : sysDeptList) {
                if(dept.getPid().equals(sysDept.getId())){
                    isChild = true;
                    if(sysDept.getChildren() == null){
                        sysDept.setChildren(new ArrayList<>());
                    }
                    sysDept.getChildren().add(dept);
                }
            }
            if(isChild){
                //这个是把有下级的加进来
                depts.add(sysDept);
            }else if(!deptIds.contains(sysDept.getPid())){
                //处理没有上一级的元素
                depts.add(sysDept);
            }

        }
        if(CollectionUtils.isEmpty(trees)){
            trees = depts;
        }
        return trees;
    }
}
